package com.rapier.sso.server.controller;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.rapier.sso.constant.RapierClientConstant;
import com.rapier.sso.constant.RapierComConstant;
import com.rapier.sso.core.config.redis.RedisClient;
import com.rapier.sso.core.convert.UserInfoConverter;
import com.rapier.sso.core.entity.TBdUserLogEntity;
import com.rapier.sso.core.entity.TDbUserBaseEntity;
import com.rapier.sso.core.model.ClientSystem;
import com.rapier.sso.core.service.IClientSystemService;
import com.rapier.sso.core.service.ITBdUserLogService;
import com.rapier.sso.core.service.ITDbUserBaseService;
import com.rapier.sso.core.store.RapierClientsPool;
import com.rapier.sso.model.ReturnModel;
import com.rapier.sso.model.UserModel;
import com.rapier.sso.server.constant.RapierServerConstant;
import com.rapier.sso.utils.ThreadLocalUtil;

@RestController
@RequestMapping("/user")
public class SsoServerUserController {

	@Autowired
	private ITBdUserLogService userLogService;

	@Autowired
	private ITDbUserBaseService userService;

	@Autowired
	private UserInfoConverter userConverter;

	@Autowired
	private RedisClient redisClient;

	@Autowired
	private RapierClientsPool clientsPool;

	@Autowired
	private IClientSystemService clientSystemService;

	/**
	 * userAdd
	 *
	 * @param serviceticket
	 * @param clientId
	 * @return
	 */
	@RequestMapping(value = "add", method = RequestMethod.POST)
	@ResponseBody
	public ReturnModel<UserModel> userAdd(@RequestBody UserModel userInfo) {
		int exist = userService.count(userService.query().eq("account", userInfo.getAccount()));
		if (exist > 0) {
			return new ReturnModel<UserModel>(ReturnModel.FAIL_CODE, "账号已经存在!");
		}
		TDbUserBaseEntity entity = userConverter.model2Entity(userInfo);
		entity.setId(null);
		userService.save(entity);
		userInfo = userConverter.entity2Model(entity);
		sendAllClient(entity, RapierClientConstant.NOTICE_USECHANGE_ADD);// 通知新增
		return new ReturnModel<UserModel>(userInfo);
	}

	/**
	 * userLogin
	 *
	 * @param serviceticket
	 * @param clientId
	 * @return
	 */
	@RequestMapping(value = "edit", method = RequestMethod.POST)
	@ResponseBody
	public ReturnModel<UserModel> userEdit(HttpServletRequest request, @RequestBody UserModel userInfo) {
		TDbUserBaseEntity entity = userService
				.getOne(userService.query().eq("account", userInfo.getAccount()).last("limit 1"), false);
		if (entity == null) {
			return new ReturnModel<UserModel>(ReturnModel.FAIL_CODE, "账号不存在!");
		}
		if (!entity.getId().equals(userInfo.getId())) {
			return new ReturnModel<UserModel>(ReturnModel.FAIL_CODE, "传递的账号信息(id)错误!");
		}
		TDbUserBaseEntity update = userConverter.model2Entity(userInfo);
		userService.update(update, userService.query().eq("id", entity.getId()));
		//全部登出
		redisClient.removePattern(RapierServerConstant.REDIS_SSO_APP_USER_ST_KEY + entity.getId() + ".*");
		redisClient.removePattern(RapierServerConstant.REDIS_SSO_USER_ST_KEY + entity.getId() + ".*");
		sendAllClient(update, RapierClientConstant.NOTICE_USECHANGE_EDIT);// 通知新增
		return new ReturnModel<UserModel>(userInfo);
	}

	/**
	 * userLogin
	 *
	 * @param serviceticket
	 * @param clientId
	 * @return
	 */
	@RequestMapping(value = "del", method = RequestMethod.POST)
	@ResponseBody
	public ReturnModel<Void> userDel(@RequestBody String userId) {
		TDbUserBaseEntity entity = userService.getById(userId);
		if (entity == null) {
			return new ReturnModel<Void>(ReturnModel.SUCCESS_CODE, "删除成功");
		}
		//全部登出
		redisClient.removePattern(RapierServerConstant.REDIS_SSO_APP_USER_ST_KEY + entity.getId() + ".*");
		redisClient.removePattern(RapierServerConstant.REDIS_SSO_USER_ST_KEY + entity.getId() + ".*");
		sendAllClient(entity, RapierClientConstant.NOTICE_USECHANGE_DEL);// 通知新增
		return new ReturnModel<Void>(ReturnModel.SUCCESS_CODE, "删除成功");
	}

	private void sendAllClient(TDbUserBaseEntity entity, String state) {
		// 保存变更日志
		TBdUserLogEntity userlogEntity = new TBdUserLogEntity();
		userlogEntity.setJson(JSONObject.toJSONString(entity));
		userlogEntity.setOptionTime(new Date());
		userlogEntity.setState(state);
		userlogEntity.setUserId(entity.getId());
		userLogService.save(userlogEntity);
		// 发送异步消息
		ClientSystem clientSystem = ThreadLocalUtil.get(RapierComConstant.RAPIER_CLIENT);
		for (ClientSystem index : clientsPool.getClients()) {
			if (clientSystem != null && clientSystem.getClient().getId().equals(index.getClient().getId())) {
				continue;
			}
			clientSystemService.noticeUserChange(clientSystem, entity.getId(), state);
		}
	}
}
